package org.vacoor.xqq.ui.chat;

import org.vacoor.nothing.ui.util.WindowMoveHandler;
import org.vacoor.xqq.core.bean.Buddy;
import org.vacoor.xqq.core.bean.Discussion;
import org.vacoor.xqq.core.bean.Group;
import org.vacoor.xqq.core.bean.Peer;
import org.vacoor.xqq.core.msg.SendableMessage;
import org.vacoor.xqq.core.poll.impl.AbstractPollReply;
import org.vacoor.xqq.core.poll.impl.MulticastReply;
import org.vacoor.xqq.ui.comp.tabpane.QuickOpTabbedPane;
import org.vacoor.xqq.ui.i.Chat2;
import org.vacoor.xqq.ui.i.ChatManager2;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.*;

/**
 * @author: vacoor
 */
public class UIChatManager2 extends JFrame implements ChatManager2 {
    private static final String TITLE = "X-QQ Chat";
    private static final String NEW_MSG_TITLE = "有新消息";
    private static final Color BACKGROUND_COLOR = new Color(0xE0EFF6);
    private static final Color NEW_MSG_TAB_COLOR = new Color(0xFFAA25);

    private Handler handler = new Handler();
    protected QuickOpTabbedPane quickOpTabbedPane;
    protected Timer titleFlasher = new Timer(300, handler);

    public UIChatManager2() {
        init();
    }

    private void init() {
        quickOpTabbedPane = new QuickOpTabbedPane(SwingConstants.TOP, JTabbedPane.WRAP_TAB_LAYOUT);

        quickOpTabbedPane.setOpaque(true);
        quickOpTabbedPane.setBorder(BorderFactory.createLineBorder(new Color(0x777777)));
        quickOpTabbedPane.setBackground(BACKGROUND_COLOR);
        quickOpTabbedPane.setEnabledTabDBClickClose(true);
        quickOpTabbedPane.setEnabledTabQuickSwitch(true);

        // -- 快捷键设置
        quickOpTabbedPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.ALT_DOWN_MASK), "CloseTab");
        quickOpTabbedPane.getActionMap().put("CloseTab", new CloseTabAction());

        this.setContentPane(quickOpTabbedPane);
        this.setTitle(TITLE);
        this.setUndecorated(true);
        this.setSize(new Dimension(500, 450));
        this.setLocationRelativeTo(null);

        new WindowMoveHandler().bindTo(quickOpTabbedPane);

        // 获取光标清理闪烁
        this.addWindowFocusListener(handler);
        quickOpTabbedPane.addChangeListener(handler);
    }

    @Override
    public Chat2 getChat(Peer peer, boolean create) {
        ChatPanel2<?> chatPanel = getChatPanel(peer);
        if (chatPanel == null && create) {
            chatPanel = createChatPanel(peer);
        }
        return chatPanel;
    }

    @Override
    public Chat2 getCurrentChat() {
        return (ChatPanel2) quickOpTabbedPane.getSelectedComponent();
    }

    @Override
    public void setCurrentChat(Chat2 chat) {
        if (chat == null) {
            return;
        }
        ChatPanel2 c = (ChatPanel2) chat;
        quickOpTabbedPane.setSelectedComponent(c);
        this.setVisible(true);
    }

    @Override
    public void notifyUser(Chat2 chat) {
        if (chat == null || !(chat instanceof ChatPanel2)) {
            return;
        }
        ChatPanel2 c = ((ChatPanel2) chat);
        int idx = quickOpTabbedPane.indexOfComponent(c);
        if (0 > idx) {
            return;
        }

        // 如果当前窗口没有激活
        if (!this.isActive()) {
            this.setIconImage(((ImageIcon) c.getChatPeer().getAvatar()).getImage());
            titleFlasher.start();
        }

        // 如果不是当前聊天 Tab
        if (chat != getCurrentChat()) {
            quickOpTabbedPane.setBackgroundAt(idx, NEW_MSG_TAB_COLOR);
        }
    }

    @Override
    public void cancelNotify(Chat2 chat) {
        // 应该不会被调用
    }

    /**
     * 重置标题
     */
    protected void resetTitle() {
        Chat2 chat = getCurrentChat();
        if (chat == null) {
            return;
        }
        Peer peer = chat.getChatPeer();
        int count = quickOpTabbedPane.getTabCount();
        String title = peer.getMark() != null ? peer.getMark() : peer.getName();
        title += count > 1 ? ("等" + count + "个会话") : "";
        this.setTitle(title);
        this.setIconImage(((ImageIcon) peer.getAvatar()).getImage());
    }

    /**
     * 获取给定联系人id 对应的 面板, 如果不存在返回null
     */
    protected ChatPanel2 getChatPanel(Peer peer) {
        for (int i = 0; i < quickOpTabbedPane.getTabCount(); i++) {
            Component c = quickOpTabbedPane.getComponent(i);
            if (!(c instanceof ChatPanel2)) {
                continue;
            }
            ChatPanel2 cp = (ChatPanel2) c;
            Peer p = cp.getChatPeer();
            if (peer.getClass().isAssignableFrom(p.getClass()) && p.getId() == peer.getId()) {
                return cp;
            }
        }
        return null;
    }

    /**
     */
    protected ChatPanel2<?> createChatPanel(Peer peer) {
        ChatPanel2<?> chat = null;
        if (peer instanceof Buddy) {
            chat = createBuddyChat((Buddy) peer);
        } else if (peer instanceof Discussion) {
            chat = createDiscuChat((Discussion) peer);
        } else if (peer instanceof Group) {
            chat = createGroupChat((Group) peer);
        }
        String title = peer.getMark();
        if (title == null || title.length() < 1) {
            title = peer.getName();
        }

        quickOpTabbedPane.addTab(title, chat);
        return chat;
    }

    protected ChatPanel2 createBuddyChat(Buddy buddy) {
        return new ChatPanel2<Buddy>(buddy) {
            @Override
            protected void doSend(SendableMessage msg, long id) {
                msg.sendToBuddy(id);
            }
        };
    }

    protected ChatPanel2<Discussion> createDiscuChat(Discussion discu) {
        return new ChatPanel2<Discussion>(discu) {
            @Override
            protected void doSend(SendableMessage msg, long id) {
                msg.sendToDiscu(id);
            }

            @Override
            protected String getSenderName(AbstractPollReply msg) {
                if (msg instanceof MulticastReply) {
                    MulticastReply multicast = (MulticastReply) msg;
                    long sendUin = multicast.getSendUin();
                    Buddy member = peer.getMember(sendUin);
                    if (member != null) {
                        String name = member.getMark() == null ? member.getNick() : member.getMark();
                        name += "(" + member.getNo() + ")";
                        return name;
                    }
                }
                return super.getSenderName(msg);
            }
        };
    }

    protected ChatPanel2<Group> createGroupChat(Group group) {
        return new ChatPanel2<Group>(group) {
            @Override
            protected void doSend(SendableMessage msg, long id) {
                msg.sendToGroup(id);
            }

            @Override
            protected String getSenderName(AbstractPollReply msg) {
                if (msg instanceof MulticastReply) {
                    MulticastReply multicast = (MulticastReply) msg;
                    long sendUin = multicast.getSendUin();
                    Buddy member = peer.getMember(sendUin);
                    if (member != null) {
                        String name = member.getMark() == null ? member.getNick() : member.getMark();
                        name += "(" + member.getNo() + ")";
                        return name;
                    }
                }
                return super.getSenderName(msg);
            }
        };
    }

    protected class CloseTabAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            if (!(source instanceof JTabbedPane)) {
                return;
            }
            JTabbedPane tabbedPane = (JTabbedPane) source;
            int idx = tabbedPane.getSelectedIndex();
            if (idx > -1) {
                tabbedPane.removeTabAt(idx);
            }
            if (tabbedPane.getTabCount() == 0) {
                setVisible(false);
            }
        }
    }


    protected class Handler extends WindowAdapter implements ChangeListener, ActionListener {

        // TabedPane 切换标签时, 取消提醒, 并且重置标题
        @Override
        public void stateChanged(ChangeEvent e) {
            Object source = e.getSource();
            if (!(source instanceof JTabbedPane)) {
                return;
            }
            JTabbedPane tabbedPane = (JTabbedPane) source;
            int idx = tabbedPane.getSelectedIndex();
            if (0 > idx) {
                return;
            }
            // 取消选中标签页的唤醒
            tabbedPane.setBackgroundAt(idx, BACKGROUND_COLOR);

            if (tabbedPane.getSelectedComponent() instanceof ChatPanel2) {
                ChatPanel2 cp = (ChatPanel2) quickOpTabbedPane.getSelectedComponent();
                cp.requestFocusForInput();
            }
            resetTitle();
        }

        // 标题栏新消息闪烁提醒
        @Override
        public void actionPerformed(ActionEvent e) {
            UIChatManager2 c = UIChatManager2.this;
            String title = c.getTitle();
            c.setTitle(title == null || title.length() == 0 ? NEW_MSG_TITLE : null);
        }

        // 获取窗体获取光标后取消标题闪烁, 重置标题
        @Override
        public void windowGainedFocus(WindowEvent e) {
            titleFlasher.stop();
            resetTitle();
        }
    }
}
